package ui;

import info.Conference;
import io.UserHasConfRoleAccess;
import io.UserHasConfRoleAccess.ConfRoleID;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import users.ProgramChair;
import users.Reviewer;
import users.Role;
import users.SubprogramChair;
import users.User;


/**
 * The splash panel that appears when the user logs in.  From here, the user
 * can either go to a role panel that he has been assigned to, or view public
 * resources such as the list of current conferences.
 * 
 * @author Aaron Chen
 * @version 3/19/2014
 */
@SuppressWarnings("serial")
public class MainPanel extends AbstractMainComponent {
  
  /** The welcome label for when the user logs in. */
  private JLabel my_label;
  
  /** The center of the MainPanel. */
  private JPanel my_panel_center;
  
  /** The combo box that displays the list of conferences the user is involved in. */
  private CustomComboBox<Object> my_combo_conference;
  
  /** The combo box that displays the list of roles the user is involved in. */
  private JComboBox<Object> my_combo_role;

  /**
   * Constructs a new MainPanel.
   * @param the_stack The display stack.
   */
  public MainPanel(final DisplayPanel the_stack) {
    super(the_stack);
    setLayout(new BorderLayout());
    my_label = new JLabel();
    my_label.setHorizontalAlignment(SwingConstants.CENTER);
    
    my_panel_center = new JPanel();
    my_panel_center.setBackground(Standards.COLOR_BACKGROUND);
    my_panel_center.setVisible(false);
    
    final JPanel panel_bottom = new JPanel();
    final JLabel lbl_alternative = new JLabel("Not in a conference, but want to participate?");
    final JButton btn_conference_list = new JButton("View Conference List");
    btn_conference_list.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent the_e) {
        final DisplayPanel dsp = getDisplayStack();
        final ConferenceListPanel clp =
            new ConferenceListPanel(dsp);
        dsp.removeFromStackUpTo();
        dsp.addToStack(clp);
      }
    });
    
    my_combo_conference = new CustomComboBox<Object>();
    my_combo_conference.addItem("Select a Conference...");
    final Dimension d = my_combo_conference.getPreferredSize();
    d.width = 300;
    my_combo_conference.setFieldSize(d);
    my_combo_role = new JComboBox<Object>();
    my_combo_role.addItem("Select a Role...");
    final JButton button_go = new JButton("Go!");
    button_go.setEnabled(false);
    my_combo_conference.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent the_e) {
        if (my_combo_conference.getSelectedIndex() > 0) {
          setRoleComboBox(MainPage.getUser());
        }
      }
    });
    my_combo_role.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent the_e) {
        if (my_combo_role.getSelectedIndex() > 0
            && my_combo_conference.getSelectedIndex() > 0) {
          button_go.setEnabled(true);
        }
      }
    });
    button_go.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent the_e) {
        if (my_combo_conference.getSelectedIndex() <= 0
            || my_combo_role.getSelectedIndex() <= 0) {
          JOptionPane.showMessageDialog(MainPanel.this,
                                        "You must select a conference role to continue.");
        } else {
          showRolePanel();
        }
      }
    });

    my_panel_center.add(my_combo_conference);
    my_panel_center.add(my_combo_role);
    my_panel_center.add(button_go);
    panel_bottom.add(lbl_alternative);
    panel_bottom.add(btn_conference_list);
    add(my_label, BorderLayout.NORTH);
    add(my_panel_center, BorderLayout.CENTER);
    add(panel_bottom, BorderLayout.SOUTH);
  }
  
  /**
   * Personalizes the panel for the user that has logged in.
   * @param the_user The User data object.
   */
  public void loadUser(final User the_user) {
    setLabel(the_user);
    setConferenceComboBox(the_user);
    my_panel_center.setVisible(true);
  }
  
  /**
   * Sets the welcome label.
   * @param the_user The User data object.
   */
  private void setLabel(final User the_user) {
    final StringBuilder sb = new StringBuilder("Welcome ");
    sb.append(the_user.getFirstName());
    sb.append(" ");
    sb.append(the_user.getLastName());
    sb.append("!  Please select your conference role.");
    //sb.append("  Alternatively, you can select a conference as a guest.")
    my_label.setText(sb.toString());
  }
  
  /**
   * Fills in items for the conference combo box for the user to select.
   * @param the_user The user that the roles belong go.
   */
  private void setConferenceComboBox(final User the_user) {
    final UserHasConfRoleAccess ucra = MainPage.getDatabase().accessUserConfRole();
    final List<ConfRoleID> roles = ucra.getConfRoles(the_user.getID());
    final Set<Long> set = new HashSet<Long>();
    my_combo_conference.removeAllItems();
    my_combo_conference.addItem("Select a Conference...");
    my_combo_role.removeAllItems();
    my_combo_role.addItem("Select a Role...");
    my_combo_role.setEnabled(false);
    for (ConfRoleID role : roles) {
      final long id = role.getConfID();
      if (!set.contains(id)) {
        set.add(id);
        final Conference c = MainPage.getDatabase().accessConf().getConference(id);
        my_combo_conference.addItem(c);
      }
    }
  }
  
  /**
   * Fills in items for the role combo box for the user to select.
   * @param the_user The user that the roles belong go.
   */
  private void setRoleComboBox(final User the_user) {
    final UserHasConfRoleAccess ucra = MainPage.getDatabase().accessUserConfRole();
    final Conference c = (Conference) my_combo_conference.getSelectedItem();
    final List<Long> roles = ucra.getRoleIDs(c.getID(), the_user.getID());
    for (Long l : roles) {
      final Role role = MainPage.getDatabase().accessRole().getRole(l);
      my_combo_role.addItem(role);
    }
    my_combo_role.setEnabled(true);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String getPanelLabel() {
    return "Main";
  }
  
  /**
   * Shows the specific panel depending on what role the user has selected.
   */
  private void showRolePanel() {
    //final Conference c = (Conference) my_combo_conference.getSelectedItem();
    final Role role = (Role) my_combo_role.getSelectedItem();
    final DisplayPanel dsp = getDisplayStack();
    switch (role.getRoleID()) {
      case Standards.ROLE_ID_PROGRAM_CHAIR:
        final ProgramChairPanel pcp = new ProgramChairPanel(dsp, (ProgramChair) role);
        dsp.addToStack(pcp);
        break;
      case Standards.ROLE_ID_SUBPROGRAM_CHAIR:
        final SubprogramChairPanel spcp = new SubprogramChairPanel(dsp,
                                                                   (SubprogramChair) role);
        dsp.addToStack(spcp);
        break;
      case Standards.ROLE_ID_AUTHOR:
        //TODO
        break;
      case Standards.ROLE_ID_REVIEWER:
        final ReviewerPanel rp = new ReviewerPanel(dsp, (Reviewer) role);
        dsp.addToStack(rp);
        break;
      default:
        JOptionPane.showMessageDialog(MainPanel.this, "Unrecognized role type.");
    }
  }

}
